#define _WIN32_DCOM
#include <windows.h>
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
#include "component\component.h"

void main()
{
    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    if(FAILED(hr))
        cout << "CoInitializeEx failed. " << endl;

	ISum* pSum = 0;

//  hr = CoCreateInstance(CLSID_InsideCOM, NULL, CLSCTX_LOCAL_SERVER, IID_ISum, (void**)&pSum);
//	if(FAILED(hr))
//	    cout << "CoCreateInstance FAILED" << endl;

	IClassFactory* pClassFactory = 0;
	CoGetClassObject(CLSID_InsideCOM, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void**)&pClassFactory);
	pClassFactory->CreateInstance(NULL, IID_ISum, (void**)&pSum);
	pClassFactory->Release();

	pSum->Initialize(6, 4);

	IUnknown* pUnknown = 0;
	hr = pSum->QueryInterface(IID_IUnknown, (void**)&pUnknown);
	if(FAILED(hr))
		cout << "QueryInterface FAILED" << endl;

	IMoniker* pMoniker = 0;
	hr = CreateObjrefMoniker(pUnknown, &pMoniker);
	if(FAILED(hr))
		cout << "CreateObjrefMoniker FAILED" << endl;

	IBindCtx* pBindCtx = 0;
	hr = CreateBindCtx(0, &pBindCtx);
	if(FAILED(hr))
		cout << "CreateBindCtx FAILED" << endl;

	OLECHAR* pString;
	hr = pMoniker->GetDisplayName(pBindCtx, NULL, &pString);
	if(FAILED(hr))
		printf("GetDisplayName FAILED %0x\n", hr);

	cout << endl << "The line below is the custom marshaled interface pointer " << endl;
	cout << "containing the persistent state of the object. Copy it to " << endl;
	cout << "the clipboard and then open and run the VBClient.vbp project." << endl;
	cout << "Paste the marshaled interface pointer into the text box and " << endl;
	cout << "click Go! You will see that the object's state is available. " << endl;
	cout << "You can even close the CPPClient program and the VB program will still work." << endl;

	// +7 to remove "objref:"
	wprintf(L"\n%s\n\n", pString+7);
	CoTaskMemFree(pString);

	// Need an extra IUnknown->Release to counter AddRef by CoMarshalInterface's QI for IMarshal
	//    during the IMoniker->GetDisplayName call.
	pUnknown->Release();

	pBindCtx->Release();
	pMoniker->Release();
	pUnknown->Release();

	int sum = 0;
	pSum->GetSum(&sum);
	cout << "GetSum = " << sum << endl;

	pSum->Release();

    CoUninitialize();
}